package com.yourcompany.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yourcompany.api.dto.RoleDTO;
import com.yourcompany.api.dto.RolePermissionDTO;
import com.yourcompany.api.dto.RoleQueryDTO;
import com.yourcompany.api.entity.Role;
import com.yourcompany.api.entity.RolePermission;
import com.yourcompany.api.mapper.RoleMapper;
import com.yourcompany.api.mapper.RolePermissionMapper;
import com.yourcompany.api.service.RoleService;
import com.yourcompany.api.vo.RoleVO;
import com.yourcompany.common.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createRole(RoleDTO roleDTO) {
        // 检查角色标识是否存在
        if (count(new LambdaQueryWrapper<Role>()
                .eq(Role::getCode, roleDTO.getCode())) > 0) {
            throw new BusinessException("角色标识已存在");
        }

        Role role = new Role();
        BeanUtils.copyProperties(roleDTO, role);
        role.setCreatorId(StpUtil.getLoginIdAsLong());
        
        save(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(Long id, RoleDTO roleDTO) {
        Role role = getById(id);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 检查是否为系统角色
        if (role.getIsSystem()) {
            throw new BusinessException("系统角色不允许修改");
        }

        // 检查角色标识是否重复
        if (!role.getCode().equals(roleDTO.getCode())) {
            if (count(new LambdaQueryWrapper<Role>()
                    .eq(Role::getCode, roleDTO.getCode())) > 0) {
                throw new BusinessException("角色标识已存在");
            }
        }

        BeanUtils.copyProperties(roleDTO, role);
        role.setModifierId(StpUtil.getLoginIdAsLong());
        
        updateById(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRole(Long id) {
        Role role = getById(id);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 检查是否为系统角色
        if (role.getIsSystem()) {
            throw new BusinessException("系统角色不允许删除");
        }

        // TODO: 检查角色是否已分配给用户
        
        // 删除角色权限关联
        rolePermissionMapper.delete(new LambdaQueryWrapper<RolePermission>()
                .eq(RolePermission::getRoleId, id));
        
        // 删除角色
        removeById(id);
    }

    @Override
    public RoleVO getRoleById(Long id) {
        Role role = getById(id);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        RoleVO roleVO = new RoleVO();
        BeanUtils.copyProperties(role, roleVO);
        return roleVO;
    }

    @Override
    public IPage<RoleVO> pageRoles(IPage<Role> page, RoleQueryDTO queryDTO) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.isNotBlank(queryDTO.getName())) {
            queryWrapper.like(Role::getName, queryDTO.getName());
        }
        if (StringUtils.isNotBlank(queryDTO.getCode())) {
            queryWrapper.like(Role::getCode, queryDTO.getCode());
        }
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(Role::getStatus, queryDTO.getStatus());
        }
        if (queryDTO.getIsSystem() != null) {
            queryWrapper.eq(Role::getIsSystem, queryDTO.getIsSystem());
        }
        
        queryWrapper.orderByAsc(Role::getSort);
        
        return page(page, queryWrapper).convert(role -> {
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(role, roleVO);
            return roleVO;
        });
    }

    @Override
    public List<RoleVO> listAllEnabledRoles() {
        List<Role> roles = list(new LambdaQueryWrapper<Role>()
                .eq(Role::getStatus, true)
                .orderByAsc(Role::getSort));

        return roles.stream().map(role -> {
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(role, roleVO);
            return roleVO;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(Long id, Boolean status) {
        Role role = getById(id);
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 检查是否为系统角色
        if (role.getIsSystem()) {
            throw new BusinessException("系统角色不允许修改状态");
        }

        role.setStatus(status);
        role.setModifierId(StpUtil.getLoginIdAsLong());
        
        updateById(role);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignPermissions(RolePermissionDTO rolePermissionDTO) {
        // 检查角色是否存在
        Role role = getById(rolePermissionDTO.getRoleId());
        if (role == null) {
            throw new BusinessException("角色不存在");
        }

        // 检查是否为系统角色
        if (role.getIsSystem()) {
            throw new BusinessException("系统角色不允许修改权限");
        }

        // 删除原有权限
        rolePermissionMapper.delete(new LambdaQueryWrapper<RolePermission>()
                .eq(RolePermission::getRoleId, rolePermissionDTO.getRoleId()));

        // 批量保存新权限
        if (!rolePermissionDTO.getPermissionIds().isEmpty()) {
            List<RolePermission> rolePermissions = rolePermissionDTO.getPermissionIds().stream()
                    .map(permissionId -> {
                        RolePermission rolePermission = new RolePermission();
                        rolePermission.setRoleId(rolePermissionDTO.getRoleId());
                        rolePermission.setPermissionId(permissionId);
                        rolePermission.setCreatorId(StpUtil.getLoginIdAsLong());
                        return rolePermission;
                    }).collect(Collectors.toList());
            
            rolePermissionMapper.insertBatch(rolePermissions);
        }
    }

    @Override
    public List<Long> getRolePermissionIds(Long roleId) {
        return rolePermissionMapper.getPermissionIdsByRoleId(roleId);
    }

    @Override
    public List<Long> getRolePermissionIds(List<Long> roleIds) {
        if (roleIds == null || roleIds.isEmpty()) {
            return new ArrayList<>();
        }
        return rolePermissionMapper.getPermissionIdsByRoleIds(roleIds);
    }
} 